home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 1 / QRZ Ham Radio Callsign Database - December 1993.iso / ucsd / packet / tcpip / sys5 / iscwmpst.z / iscwmpst / tcp / src / netrom.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-06-05  |  56.6 KB  |  2,215 lines

  1. /* @(#) $Header: netrom.c,v 1.23 91/06/04 11:34:33 deyke Exp $ */
  2.  
  3. #include <ctype.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7.  
  8. #include "global.h"
  9. #include "config.h"
  10. #include "netuser.h"
  11. #include "mbuf.h"
  12. #include "timer.h"
  13. #include "iface.h"
  14. #include "arp.h"
  15. #include "ip.h"
  16. #include "ax25.h"
  17. #include "lapb.h"
  18. #include "netrom.h"
  19. #include "cmdparse.h"
  20.  
  21. static int  nr_maxdest     =   400;     /* not used */
  22. static int  nr_minqual     =     0;     /* not used */
  23. static int  nr_hfqual      =   192;
  24. static int  nr_rsqual      =   255;     /* not used */
  25. static int  nr_obsinit     =     3;
  26. static int  nr_minobs      =     0;     /* not used */
  27. static int  nr_bdcstint    =  1800;
  28. static int  nr_ttlinit     =    16;
  29. static int  nr_ttimeout    =    60;
  30. static int  nr_tretry      =     5;
  31. static int  nr_tackdelay   =  1900;
  32. static int  nr_tbsydelay   =   180;
  33. static int  nr_twindow     =     8;
  34. static int  nr_tnoackbuf   =     8;
  35. static int  nr_timeout     =  1800;
  36. static int  nr_persistance =    64;     /* not used */
  37. static int  nr_slottime    =    10;     /* not used */
  38. static int  nr_callcheck   =     0;     /* not used */
  39. static int  nr_beacon      =     0;     /* not used */
  40. static int  nr_cq          =     0;     /* not used */
  41.  
  42. static struct parms {
  43.   char  *text;
  44.   int  *valptr;
  45.   int  minval;
  46.   int  maxval;
  47. } parms[] = {
  48.   "",                                               (int *) 0,       0,          0,
  49.   " 1 Maximum destination list entries           ", &nr_maxdest,     1,        400,
  50.   " 2 Worst quality for auto-updates             ", &nr_minqual,     0,        255,
  51.   " 3 Channel 0 (HDLC) quality                   ", &nr_hfqual,      0,        255,
  52.   " 4 Channel 1 (RS232) quality                  ", &nr_rsqual,      0,        255,
  53.   " 5 Obsolescence count initializer (0=off)     ", &nr_obsinit,     0,        255,
  54.   " 6 Obsolescence count min to be broadcast     ", &nr_minobs,      0,        255,
  55.   " 7 Auto-update broadcast interval (sec, 0=off)", &nr_bdcstint,    0,      65535,
  56.   " 8 Network 'time-to-live' initializer         ", &nr_ttlinit,     1,        255,
  57.   " 9 Transport timeout (sec)                    ", &nr_ttimeout,    5,        600,
  58.   "10 Transport maximum tries                    ", &nr_tretry,      1,        127,
  59.   "11 Transport acknowledge delay (ms)           ", &nr_tackdelay,   1,      60000,
  60.   "12 Transport busy delay (sec)                 ", &nr_tbsydelay,   1,       1000,
  61.   "13 Transport requested window size (frames)   ", &nr_twindow,     1,        127,
  62.   "14 Congestion control threshold (frames)      ", &nr_tnoackbuf,   1,        127,
  63.   "15 No-activity timeout (sec, 0=off)           ", &nr_timeout,     0,      65535,
  64.   "16 Persistance                                ", &nr_persistance, 0,        255,
  65.   "17 Slot time (10msec increments)              ", &nr_slottime,    0,        127,
  66.   "18 Link T1 timeout 'FRACK' (ms)               ", &ax_t1init,      1, 0x7fffffff,
  67.   "19 Link TX window size 'MAXFRAME' (frames)    ", &ax_maxframe,    1,          7,
  68.   "20 Link maximum tries (0=forever)             ", &ax_retry,       0,        127,
  69.   "21 Link T2 timeout (ms)                       ", &ax_t2init,      1, 0x7fffffff,
  70.   "22 Link T3 timeout (ms)                       ", &ax_t3init,      0, 0x7fffffff,
  71.   "23 AX.25 digipeating  (0=off 1=dumb 2=s&f)    ", &Digipeat,       0,          2,
  72.   "24 Validate callsigns (0=off 1=on)            ", &nr_callcheck,   0,          1,
  73.   "25 Station ID beacons (0=off 1=after 2=every) ", &nr_beacon,      0,          2,
  74.   "26 CQ UI frames       (0=off 1=on)            ", &nr_cq,          0,          1,
  75. };
  76.  
  77. #define NPARMS 26
  78.  
  79. static struct node *nodeptr __ARGS((char *call, int create));
  80. static void ax25_state_upcall __ARGS((struct ax25_cb *cp, int oldstate, int newstate));
  81. static void ax25_recv_upcall __ARGS((struct ax25_cb *cp, int cnt));
  82. static void send_packet_to_neighbor __ARGS((struct mbuf *data, struct node *pn));
  83. static void send_broadcast_packet __ARGS((struct mbuf *data));
  84. static void link_manager_initialize __ARGS((void));
  85. static struct linkinfo *linkinfoptr __ARGS((struct node *node1, struct node *node2));
  86. static int update_link __ARGS((struct node *node1, struct node *node2, int level, int quality));
  87. static void calculate_node __ARGS((struct node *pn));
  88. static void calculate_all __ARGS((void));
  89. static void broadcast_recv __ARGS((struct mbuf *bp, struct node *pn));
  90. static struct mbuf *alloc_broadcast_packet __ARGS((void));
  91. static void send_broadcast __ARGS((void));
  92. static void route_packet __ARGS((struct mbuf *bp, struct node *fromneighbor));
  93. static void send_l3_packet __ARGS((char *source, char *dest, int ttl, struct mbuf *data));
  94. static void routing_manager_initialize __ARGS((void));
  95. static void reset_t1 __ARGS((struct circuit *pc));
  96. static void inc_t1 __ARGS((struct circuit *pc));
  97. static int busy __ARGS((struct circuit *pc));
  98. static void send_l4_packet __ARGS((struct circuit *pc, int opcode, struct mbuf *data));
  99. static void try_send __ARGS((struct circuit *pc, int fill_sndq));
  100. static void set_circuit_state __ARGS((struct circuit *pc, int newstate));
  101. static void l4_t1_timeout __ARGS((struct circuit *pc));
  102. static void l4_t2_timeout __ARGS((struct circuit *pc));
  103. static void l4_t3_timeout __ARGS((struct circuit *pc));
  104. static void l4_t4_timeout __ARGS((struct circuit *pc));
  105. static void l4_t5_timeout __ARGS((struct circuit *pc));
  106. static struct circuit *create_circuit __ARGS((void));
  107. static void circuit_manager __ARGS((struct mbuf *bp));
  108. static void nrserv_recv_upcall __ARGS((struct circuit *pc, int cnt));
  109. static void nrserv_send_upcall __ARGS((struct circuit *pc, int cnt));
  110. static void nrserv_state_upcall __ARGS((struct circuit *pc, int oldstate, int newstate));
  111. static void nrclient_parse __ARGS((char *buf, int n));
  112. static void nrclient_state_upcall __ARGS((struct circuit *pc, int oldstate, int newstate));
  113. static int donconnect __ARGS((int argc, char *argv [], void *p));
  114. static int dobroadcast __ARGS((int argc, char *argv [], void *p));
  115. static int doident __ARGS((int argc, char *argv [], void *p));
  116. static int dolinks __ARGS((int argc, char *argv [], void *p));
  117. static int donodes __ARGS((int argc, char *argv [], void *p));
  118. static int doparms __ARGS((int argc, char *argv [], void *p));
  119. static int donreset __ARGS((int argc, char *argv [], void *p));
  120. static int donstatus __ARGS((int argc, char *argv [], void *p));
  121.  
  122. /*---------------------------------------------------------------------------*/
  123. /******************************** Link Manager *******************************/
  124. /*---------------------------------------------------------------------------*/
  125.  
  126. #define IDENTLEN     6
  127. #define MAXLEVEL   256
  128.  
  129. struct broadcast {
  130.   struct ax25 hdr;
  131.   struct iface *iface;
  132.   struct broadcast *next;
  133. };
  134.  
  135. struct node {
  136.   char  *call;
  137.   char  ident[IDENTLEN];
  138.   int  level;
  139.   struct link *links;
  140.   struct node *neighbor, *old_neighbor;
  141.   double  quality, old_quality, tmp_quality;
  142.   int  force_broadcast;
  143.   struct ax25_cb *crosslink;
  144.   struct node *prev, *next;
  145. };
  146.  
  147. /* NET/ROM broadcast address: "NODES-0" in shifted ascii */
  148. char Nr_nodebc[AXALEN] = {
  149.     'N'<<1, 'O'<<1, 'D'<<1, 'E'<<1, 'S'<<1, ' '<<1, '0'<<1
  150. };
  151.  
  152. struct ax25_cb *netrom_server_axcb;
  153.  
  154. static struct broadcast *broadcasts;
  155. static struct node *nodes, *mynode;
  156.  
  157. /*---------------------------------------------------------------------------*/
  158.  
  159. static struct node *nodeptr(call, create)
  160. char  *call;
  161. int  create;
  162. {
  163.   struct node *pn;
  164.  
  165.   for (pn = nodes; pn && !addreq(call, pn->call); pn = pn->next) ;
  166.   if (!pn && create) {
  167.     pn = (struct node *) calloc(1, sizeof(struct node ));
  168.     pn->call = malloc(AXALEN);
  169.     addrcp(pn->call, call);
  170.     memset(pn->ident, ' ', IDENTLEN);
  171.     pn->level = MAXLEVEL;
  172.     if (nodes) {
  173.       pn->next = nodes;
  174.       nodes->prev = pn;
  175.     }
  176.     nodes = pn;
  177.   }
  178.   return pn;
  179. }
  180.  
  181. /*---------------------------------------------------------------------------*/
  182.  
  183. static void ax25_state_upcall(cp, oldstate, newstate)
  184. struct ax25_cb *cp;
  185. int  oldstate, newstate;
  186. {
  187.   struct node *pn;
  188.  
  189.   if (cp->user)
  190.     pn = (struct node *) cp->user;
  191.   else
  192.     cp->user = (char *) (pn = nodeptr(cp->hdr.dest, 1));
  193.   switch (newstate) {
  194.   case CONNECTING:
  195.     break;
  196.   case CONNECTED:
  197.     pn->crosslink = cp;
  198.     if (update_link(mynode, pn, 1, nr_hfqual)) calculate_all();
  199.     break;
  200.   case DISCONNECTING:
  201.     if (cp->reason != NORMAL)
  202.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  203.     break;
  204.   case DISCONNECTED:
  205.     pn->crosslink = NULLAXCB;
  206.     if (cp->reason != NORMAL)
  207.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  208.     del_ax(cp);
  209.     break;
  210.   }
  211. }
  212.  
  213. /*---------------------------------------------------------------------------*/
  214.  
  215. static void ax25_recv_upcall(cp, cnt)
  216. struct ax25_cb *cp;
  217. int  cnt;
  218. {
  219.  
  220.   int  pid;
  221.   struct mbuf *bp;
  222.  
  223.   while (cp->rcvq) {
  224.     recv_ax(cp, &bp, 0);
  225.     if ((pid = PULLCHAR(&bp)) == -1) continue;
  226.     if (pid == PID_NETROM)
  227.       nr3_input(bp, cp->hdr.dest);
  228.     else
  229.       free_p(bp);
  230.   }
  231. }
  232.  
  233. /*---------------------------------------------------------------------------*/
  234.  
  235. static void send_packet_to_neighbor(data, pn)
  236. struct mbuf *data;
  237. struct node *pn;
  238. {
  239.  
  240.   char  path[10*AXALEN];
  241.   struct mbuf *bp;
  242.  
  243.   if (!pn->crosslink) {
  244.     addrcp(path, pn->call);
  245.     addrcp(path + AXALEN, Mycall);
  246.     path[AXALEN+6] |= E;
  247.     pn->crosslink = open_ax(path, AX_ACTIVE, ax25_recv_upcall, NULLVFP, ax25_state_upcall, (char *) pn);
  248.     if (!pn->crosslink) {
  249.       if (update_link(mynode, pn, 1, 0)) calculate_all();
  250.       free_p(data);
  251.       return;
  252.     }
  253.     pn->crosslink->mode = DGRAM;
  254.   }
  255.   if (!(bp = pushdown(data, 1))) {
  256.     free_p(data);
  257.     return;
  258.   }
  259.   bp->data[0] = PID_NETROM;
  260.   send_ax(pn->crosslink, bp);
  261. }
  262.  
  263. /*---------------------------------------------------------------------------*/
  264.  
  265. static void send_broadcast_packet(data)
  266. struct mbuf *data;
  267. {
  268.  
  269.   struct broadcast *p;
  270.   struct mbuf *bp, *bp1;
  271.  
  272.   for (p = broadcasts; p; p = p->next) {
  273.     addrcp(p->hdr.source, p->iface->hwaddr);
  274.     dup_p(&bp, data, 0, MAXINT16);
  275.     if (!(bp1 = htonax25(&p->hdr, bp)))
  276.       free_p(bp);
  277.     else if (p->iface->forw)
  278.       (*p->iface->forw->raw)(p->iface->forw, bp1);
  279.     else
  280.       (*p->iface->raw)(p->iface, bp1);
  281.   }
  282.   free_p(data);
  283. }
  284.  
  285. /*---------------------------------------------------------------------------*/
  286.  
  287. static void link_manager_initialize()
  288. {
  289.  
  290.   mynode = nodeptr(Mycall, 1);
  291.   free(mynode->call);
  292.   mynode->call = Mycall;
  293.   calculate_all();
  294.  
  295.   netrom_server_axcb = open_ax(NULLCHAR, AX_SERVER, ax25_recv_upcall, NULLVFP, ax25_state_upcall, NULLCHAR);
  296.   netrom_server_axcb->mode = DGRAM;
  297.  
  298. }
  299.  
  300. /*---------------------------------------------------------------------------*/
  301. /****************************** Routing Manager ******************************/
  302. /*---------------------------------------------------------------------------*/
  303.  
  304. #define NRRTDESTLEN     21              /* length of destination entry in */
  305.                     /* nodes broadcast */
  306. #define PERMANENT       0x7fffffff      /* Max long integer */
  307.  
  308. struct link {
  309.   struct node *node;
  310.   struct linkinfo *info;
  311.   struct link *prev, *next;
  312. };
  313.  
  314. struct linkinfo {
  315.   int  level;
  316.   int  quality;
  317.   long  time;
  318. };
  319.  
  320. struct routes_stat {
  321.   int  rcvd;
  322.   int  sent;
  323. };
  324.  
  325. static struct iface *Nr_iface;
  326. static struct routes_stat routes_stat;
  327. static struct timer broadcast_timer;
  328.  
  329. /*---------------------------------------------------------------------------*/
  330.  
  331. int  isnetrom(call)
  332. char  *call;
  333. {
  334.   return (nodeptr(call, 0) != 0);
  335. }
  336.  
  337. /*---------------------------------------------------------------------------*/
  338.  
  339. static struct linkinfo *linkinfoptr(node1, node2)
  340. struct node *node1, *node2;
  341. {
  342.  
  343.   struct link *pl;
  344.   struct linkinfo *pi;
  345.  
  346.   for (pl = node1->links; pl; pl = pl->next)
  347.     if (pl->node == node2) return pl->info;
  348.   pi = (struct linkinfo *) calloc(1, sizeof(struct linkinfo ));
  349.   pi->level = MAXLEVEL;
  350.   pl = (struct link *) calloc(1, sizeof(struct link ));
  351.   pl->node = node2;
  352.   pl->info = pi;
  353.   if (node1->links) {
  354.     pl->next = node1->links;
  355.     node1->links->prev = pl;
  356.   }
  357.   node1->links = pl;
  358.   pl = (struct link *) calloc(1, sizeof(struct link ));
  359.   pl->node = node1;
  360.   pl->info = pi;
  361.   if (node2->links) {
  362.     pl->next = node2->links;
  363.     node2->links->prev = pl;
  364.   }
  365.   node2->links = pl;
  366.   return pi;
  367. }
  368.  
  369. /*---------------------------------------------------------------------------*/
  370.  
  371. static int  update_link(node1, node2, level, quality)
  372. struct node *node1, *node2;
  373. int  level, quality;
  374. {
  375.  
  376.   int  ret;
  377.   struct linkinfo *pi;
  378.  
  379.   if (node1 == node2) return 0;
  380.   if (level > node1->level + 1 || level > node2->level + 1) return 0;
  381.   pi = linkinfoptr(node1, node2);
  382.   if (pi->level < level || pi->time == PERMANENT) return 0;
  383.   ret = 0;
  384.   if (pi->level != level) {
  385.     pi->level = level;
  386.     ret = 1;
  387.   }
  388.   if (quality > 255) quality = 255;
  389.   if (pi->quality != quality) {
  390.     pi->quality = quality;
  391.     ret = 1;
  392.   }
  393.   pi->time = secclock();
  394.   if (node1->level > level) {
  395.     node1->level = level;
  396.     ret = 1;
  397.   }
  398.   if (node2->level > level) {
  399.     node2->level = level;
  400.     ret = 1;
  401.   }
  402.   return ret;
  403. }
  404.  
  405. /*---------------------------------------------------------------------------*/
  406.  
  407. static void calculate_node(pn)
  408. struct node *pn;
  409. {
  410.  
  411.   double  quality;
  412.   struct link *pl;
  413.  
  414.   for (pl = pn->links; pl; pl = pl->next) {
  415.     quality = pn->tmp_quality * pl->info->quality / 256.0;
  416.     if (pl->node->tmp_quality < quality) {
  417.       pl->node->tmp_quality = quality;
  418.       calculate_node(pl->node);
  419.     }
  420.   }
  421. }
  422.  
  423. /*---------------------------------------------------------------------------*/
  424.  
  425. static void calculate_all()
  426. {
  427.  
  428.   int  start_broadcast_timer;
  429.   long  timelimit;
  430.   struct link *pl1, *plnext;
  431.   struct link *pl;
  432.   struct node *neighbor;
  433.   struct node *pn1, *pnnext;
  434.   struct node *pn;
  435.  
  436.   /*** remove obsolete links ***/
  437.  
  438.   if (nr_obsinit && nr_bdcstint)
  439.     timelimit = secclock() - nr_obsinit * nr_bdcstint;
  440.   else
  441.     timelimit = 0;
  442.   for (pn = nodes; pn; pn = pn->next)
  443.     for (pl = pn->links; pl; pl = plnext) {
  444.       plnext = pl->next;
  445.       if (pl->info->time < timelimit ||
  446.       pl->info->time != PERMANENT && pl->info->level > pn->level + 1) {
  447.     if (pl->prev) pl->prev->next = pl->next;
  448.     if (pl->next) pl->next->prev = pl->prev;
  449.     if (pl == pn->links) pn->links = pl->next;
  450.     pn1 = pl->node;
  451.     for (pl1 = pn1->links; pl1->node != pn; pl1 = pl1->next) ;
  452.     if (pl1->prev) pl1->prev->next = pl1->next;
  453.     if (pl1->next) pl1->next->prev = pl1->prev;
  454.     if (pl1 == pn1->links) pn1->links = pl1->next;
  455.     free(pl->info);
  456.     free(pl1);
  457.     free(pl);
  458.       }
  459.     }
  460.  
  461.   /*** fix node levels ***/
  462.  
  463.   for (pn = nodes; pn; pn = pn->next) {
  464.     pn->level = MAXLEVEL;
  465.     for (pl = pn->links; pl; pl = pl->next)
  466.       if (pn->level > pl->info->level) pn->level = pl->info->level;
  467.   }
  468.   mynode->level = 0;
  469.  
  470.   /*** preset neighbor and quality ***/
  471.  
  472.   for (pn = nodes; pn; pn = pn->next) {
  473.     pn->old_neighbor = pn->neighbor;
  474.     pn->neighbor = 0;
  475.     pn->old_quality = pn->quality;
  476.     pn->quality = 0.0;
  477.   }
  478.  
  479.   /*** calculate new neighbor and quality values ***/
  480.  
  481.   for (pl = mynode->links; pl; pl = pl->next) {
  482.     for (pn = nodes; pn; pn = pn->next) pn->tmp_quality = 0.0;
  483.     mynode->tmp_quality = 256.0;
  484.     neighbor = pl->node;
  485.     neighbor->tmp_quality = pl->info->quality;
  486.     calculate_node(neighbor);
  487.     for (pn = nodes; pn; pn = pn->next)
  488.       if (pn->quality < pn->tmp_quality ||
  489.       pn->quality == pn->tmp_quality && neighbor == pn->old_neighbor) {
  490.     pn->quality = pn->tmp_quality;
  491.     pn->neighbor = neighbor;
  492.       }
  493.   }
  494.   mynode->neighbor = 0;
  495.   mynode->quality = 256.0;
  496.  
  497.   /*** check changes ***/
  498.  
  499.   start_broadcast_timer = 0;
  500.   for (pn = nodes; pn; pn = pn->next) {
  501.     if (pn != mynode &&
  502.     (pn->neighbor != pn->old_neighbor ||
  503.     ((int) pn->quality) != ((int) pn->old_quality)))
  504.       pn->force_broadcast = 1;
  505.     if (pn->force_broadcast) start_broadcast_timer = 1;
  506.   }
  507. #ifdef FORCE_BC
  508.   if (start_broadcast_timer) {
  509.     set_timer(&broadcast_timer, 10 * 1000L);
  510.     start_timer(&broadcast_timer);
  511.   }
  512. #endif
  513.  
  514.   /*** remove obsolete nodes ***/
  515.  
  516.   for (pn = nodes; pn; pn = pnnext) {
  517.     pnnext = pn->next;
  518.     if (pn != mynode && !pn->links && !pn->crosslink && !pn->force_broadcast) {
  519.       if (pn->prev) pn->prev->next = pn->next;
  520.       if (pn->next) pn->next->prev = pn->prev;
  521.       if (pn == nodes) nodes = pn->next;
  522.       free(pn->call);
  523.       free(pn);
  524.     }
  525.   }
  526. }
  527.  
  528. /*---------------------------------------------------------------------------*/
  529.  
  530. void new_neighbor(call)
  531. char  *call;
  532. {
  533.   if (update_link(mynode, nodeptr(call, 1), 1, nr_hfqual))
  534.     calculate_all();
  535. }
  536.  
  537. /*---------------------------------------------------------------------------*/
  538.  
  539. static void broadcast_recv(bp, pn)
  540. struct mbuf *bp;
  541. struct node *pn;
  542. {
  543.  
  544.   char  buf[NRRTDESTLEN];
  545.   char  ident[IDENTLEN];
  546.   int  quality;
  547.   struct linkinfo *pi;
  548.   struct node *pb, *pd;
  549.  
  550.   routes_stat.rcvd++;
  551.   if (pn == mynode) goto discard;
  552.   if (PULLCHAR(&bp) != 0xff) goto discard;
  553.   if (pullup(&bp, ident, IDENTLEN) != IDENTLEN) goto discard;
  554.   if (len_p(bp) % NRRTDESTLEN) goto discard;
  555.   if (*ident > ' ') memcpy(pn->ident, ident, IDENTLEN);
  556.   update_link(mynode, pn, 1, nr_hfqual);
  557.   while (pullup(&bp, buf, NRRTDESTLEN) == NRRTDESTLEN) {
  558.     if (ismycall(buf)) continue;
  559.     pd = nodeptr(buf, 1);
  560.     if (buf[AXALEN] > ' ') memcpy(pd->ident, buf + AXALEN, IDENTLEN);
  561.     pb = nodeptr(buf + AXALEN + IDENTLEN, 1);
  562.     quality = uchar(buf[AXALEN+IDENTLEN+AXALEN]);
  563.     if (pb == mynode) {
  564.       if (quality >= pd->quality) pd->force_broadcast = 1;
  565.       continue;
  566.     }
  567.     if (pn == pb || pb == pd)
  568.       update_link(pn, pd, 2, quality);
  569.     else {
  570.       pi = linkinfoptr(pn, pb);
  571.       if (pi->time != PERMANENT) pi->time = secclock();
  572.       if (pi->quality) {
  573.     int  q = quality * 256 / pi->quality;
  574.     while (q * pi->quality / 256 < quality) q++;
  575.     quality = q;
  576.       }
  577.       update_link(pb, pd, 3, quality);
  578.     }
  579.   }
  580.   calculate_all();
  581.  
  582. discard:
  583.   free_p(bp);
  584. }
  585.  
  586. /*---------------------------------------------------------------------------*/
  587.  
  588. static struct mbuf *alloc_broadcast_packet()
  589. {
  590.   struct mbuf *bp;
  591.  
  592.   if (bp = alloc_mbuf(258)) {
  593.     bp->data[0] = UI;
  594.     bp->data[1] = PID_NETROM;
  595.     bp->data[2] = 0xff;
  596.     memcpy(bp->data + 3, mynode->ident, IDENTLEN);
  597.     bp->cnt = 3 + IDENTLEN;
  598.   }
  599.   return bp;
  600. }
  601.  
  602. /*---------------------------------------------------------------------------*/
  603.  
  604. static void send_broadcast()
  605. {
  606.  
  607.   char  *p;
  608.   int  level, nextlevel;
  609.   struct mbuf *bp;
  610.   struct node *pn;
  611.  
  612.   set_timer(&broadcast_timer, nr_bdcstint * 1000L);
  613.   start_timer(&broadcast_timer);
  614.   if (!broadcasts) return;
  615.   bp = alloc_broadcast_packet();
  616.   for (level = 1; level <= MAXLEVEL; level = nextlevel) {
  617.     nextlevel = MAXLEVEL + 1;
  618.     for (pn = nodes; pn; pn = pn->next)
  619.       if (pn->level >= level && (((int) pn->quality) || pn->force_broadcast))
  620.     if (pn->level == level) {
  621.       pn->force_broadcast = 0;
  622.       if (!bp) bp = alloc_broadcast_packet();
  623.       p = bp->data + bp->cnt;
  624.       addrcp(p, pn->call);
  625.       p += AXALEN;
  626.       memcpy(p, pn->ident, IDENTLEN);
  627.       p += IDENTLEN;
  628.       addrcp(p, pn->neighbor ? pn->neighbor->call : pn->call);
  629.       p += AXALEN;
  630.       *p++ = pn->quality;
  631.       if ((bp->cnt = p - bp->data) > 258 - NRRTDESTLEN) {
  632.         send_broadcast_packet(bp);
  633.         routes_stat.sent++;
  634.         bp = NULLBUF;
  635.       }
  636.     } else if (pn->level < nextlevel)
  637.       nextlevel = pn->level;
  638.   }
  639.   if (bp) {
  640.     send_broadcast_packet(bp);
  641.     routes_stat.sent++;
  642.   }
  643. }
  644.  
  645. /*---------------------------------------------------------------------------*/
  646.  
  647. static void route_packet(bp, fromneighbor)
  648. struct mbuf *bp;
  649. struct node *fromneighbor;
  650. {
  651.  
  652.   int  ttl;
  653.   struct node *pn;
  654.  
  655.   if (!bp || bp->cnt < 15) goto discard;
  656.  
  657.   if (fromneighbor != mynode) {
  658.     if (update_link(mynode, fromneighbor, 1, nr_hfqual)) calculate_all();
  659.     pn = nodeptr(bp->data, 1);
  660.     if (pn == mynode) goto discard;  /* ROUTING ERROR */
  661.     if (!pn->neighbor) {
  662.       struct linkinfo *pi = linkinfoptr(mynode, fromneighbor);
  663.       if (pi->quality) {
  664.     int  q = 1;
  665.     while (q * pi->quality / 256 < 1) q++;
  666.     if (update_link(fromneighbor, pn, 2, q)) calculate_all();
  667.       }
  668.     }
  669.   }
  670.  
  671.   if (ismycall(bp->data + AXALEN)) {
  672.     if (bp->cnt >= 40                     &&
  673.     uchar(bp->data[19]) == 0          &&
  674.     uchar(bp->data[15]) == NRPROTO_IP &&
  675.     uchar(bp->data[16]) == NRPROTO_IP &&
  676.     Nr_iface) {
  677.       arp_add(get32(bp->data + 32), ARP_NETROM, bp->data, 0);
  678.       pullup(&bp, NULLCHAR, 20);
  679.       ip_route(Nr_iface, bp, 0);
  680.       return;
  681.     }
  682.     pullup(&bp, NULLCHAR, 15);
  683.     if (!bp) return;
  684.     if (fromneighbor == mynode) {
  685.       struct mbuf *hbp = copy_p(bp, len_p(bp));
  686.       free_p(bp);
  687.       bp = hbp;
  688.     }
  689.     circuit_manager(bp);
  690.     return;
  691.   }
  692.  
  693.   ttl = uchar(bp->data[2*AXALEN]);
  694.   if (--ttl <= 0) goto discard;
  695.   bp->data[2*AXALEN] = ttl;
  696.  
  697.   pn = nodeptr(bp->data + AXALEN, 1);
  698.   if (!pn->neighbor) {
  699.     if (fromneighbor != mynode) {
  700.       pn->force_broadcast = 1;
  701. #ifdef FORCE_BC
  702.       send_broadcast();
  703. #endif
  704.     }
  705.     goto discard;
  706.   }
  707.  
  708. #ifdef FORCE_BC
  709.   if (pn->neighbor == fromneighbor ||
  710.       addreq(pn->neighbor->call, bp->data)) send_broadcast();
  711. #endif
  712.  
  713.   send_packet_to_neighbor(bp, pn->neighbor);
  714.   return;
  715.  
  716. discard:
  717.   free_p(bp);
  718. }
  719.  
  720. /*---------------------------------------------------------------------------*/
  721.  
  722. static void send_l3_packet(source, dest, ttl, data)
  723. char  *source, *dest;
  724. int  ttl;
  725. struct mbuf *data;
  726. {
  727.   struct mbuf *bp;
  728.  
  729.   if (!(bp = pushdown(data, 2 * AXALEN + 1))) {
  730.     free_p(data);
  731.     return;
  732.   }
  733.   addrcp(bp->data, source);
  734.   addrcp(bp->data + AXALEN, dest);
  735.   if (++ttl > 255) ttl = 255;
  736.   bp->data[2*AXALEN] = ttl;
  737.   route_packet(bp, mynode);
  738. }
  739.  
  740. /*---------------------------------------------------------------------------*/
  741.  
  742. int  nr_send(bp, iface, gateway, prec, del, tput, rel)
  743. struct mbuf *bp;
  744. struct iface *iface;
  745. int32 gateway;
  746. int  prec;
  747. int  del;
  748. int  tput;
  749. int  rel;
  750. {
  751.  
  752.   struct arp_tab *arp;
  753.   struct mbuf *nbp;
  754.  
  755.   if (!(arp = arp_lookup(ARP_NETROM, gateway))) {
  756.     free_p(bp);
  757.     return 0;
  758.   }
  759.   if (!(nbp = pushdown(bp, 5))) {
  760.     free_p(bp);
  761.     return 0;
  762.   }
  763.   bp = nbp;
  764.   bp->data[0] = NRPROTO_IP;
  765.   bp->data[1] = NRPROTO_IP;
  766.   bp->data[2] = 0;
  767.   bp->data[3] = 0;
  768.   bp->data[4] = 0;
  769.   send_l3_packet(Mycall, arp->hw_addr, nr_ttlinit, bp);
  770.   return 0;
  771. }
  772.  
  773. /*---------------------------------------------------------------------------*/
  774.  
  775. void nr3_input(bp, fromcall)
  776. struct mbuf *bp;
  777. char  *fromcall;
  778. {
  779.   if (bp && bp->cnt && uchar(*bp->data) == 0xff)
  780.     broadcast_recv(bp, nodeptr(fromcall, 1));
  781.   else
  782.     route_packet(bp, nodeptr(fromcall, 1));
  783. }
  784.  
  785. /*---------------------------------------------------------------------------*/
  786.  
  787. static void routing_manager_initialize()
  788. {
  789.   broadcast_timer.func = (void (*) __ARGS((void *))) send_broadcast;
  790.   set_timer(&broadcast_timer, 10 * 1000L);
  791.   start_timer(&broadcast_timer);
  792. }
  793.  
  794. /*---------------------------------------------------------------------------*/
  795. /****************************** Circuit Manager ******************************/
  796. /*---------------------------------------------------------------------------*/
  797.  
  798. #include "netrom.h"
  799.  
  800. static char  *nrreasons[] = {
  801.   "Normal",
  802.   "Reset",
  803.   "Timeout",
  804.   "Network"
  805. };
  806.  
  807. static int  server_enabled;
  808. static struct circuit *circuits;
  809.  
  810. /*---------------------------------------------------------------------------*/
  811.  
  812. char  *nr_addr2str(pc)
  813. struct circuit *pc;
  814. {
  815.  
  816.   char  *p;
  817.   static char  buf[128];
  818.  
  819.   pax25(p = buf, pc->cuser);
  820.   while (*p) p++;
  821.   *p++ = ' ';
  822.   if (pc->outbound) {
  823.     *p++ = '-';
  824.     *p++ = '>';
  825.   } else
  826.     *p++ = '@';
  827.   *p++ = ' ';
  828.   pax25(p, pc->node);
  829.   return buf;
  830. }
  831.  
  832. /*---------------------------------------------------------------------------*/
  833.  
  834. static void reset_t1(pc)
  835. struct circuit *pc;
  836. {
  837.   int32 tmp;
  838.  
  839.   tmp = pc->srtt + 2 * pc->mdev;
  840.   set_timer(&pc->timer_t1, tmp > 0 ? tmp : 1);
  841. }
  842.  
  843. /*---------------------------------------------------------------------------*/
  844.  
  845. static void inc_t1(pc)
  846. struct circuit *pc;
  847. {
  848.   int32 tmp;
  849.  
  850.   tmp = (dur_timer(&pc->timer_t1) * 5 + 2) / 4;
  851.   if (tmp > 10 * pc->srtt) tmp = 10 * pc->srtt;
  852.   set_timer(&pc->timer_t1, tmp > 0 ? tmp : 1);
  853. }
  854.  
  855. /*---------------------------------------------------------------------------*/
  856.  
  857. static int  busy(pc)
  858. struct circuit *pc;
  859. {
  860.   return pc->rcvcnt >= nr_tnoackbuf * NR4MAXINFO;
  861. }
  862.  
  863. /*---------------------------------------------------------------------------*/
  864.  
  865. static void send_l4_packet(pc, opcode, data)
  866. struct circuit *pc;
  867. int  opcode;
  868. struct mbuf *data;
  869. {
  870.  
  871.   int  start_t1_timer = 0;
  872.   struct mbuf *bp;
  873.  
  874.   switch (opcode & NR4OPCODE) {
  875.   case NR4OPCONRQ:
  876.     if (!(bp = pushdown(data, 20))) {
  877.       free_p(data);
  878.       return;
  879.     }
  880.     bp->data[0] = pc->localindex;
  881.     bp->data[1] = pc->localid;
  882.     bp->data[2] = 0;
  883.     bp->data[3] = 0;
  884.     bp->data[4] = opcode;
  885.     bp->data[5] = pc->window;
  886.     addrcp(bp->data + 6, pc->cuser);
  887.     addrcp(bp->data + 13, Mycall);
  888.     start_t1_timer = 1;
  889.     break;
  890.   case NR4OPCONAK:
  891.     if (!(bp = pushdown(data, 6))) {
  892.       free_p(data);
  893.       return;
  894.     }
  895.     bp->data[0] = pc->remoteindex;
  896.     bp->data[1] = pc->remoteid;
  897.     bp->data[2] = pc->localindex;
  898.     bp->data[3] = pc->localid;
  899.     bp->data[4] = opcode;
  900.     bp->data[5] = pc->window;
  901.     break;
  902.   case NR4OPDISRQ:
  903.     start_t1_timer = 1;
  904.   case NR4OPDISAK:
  905.     if (!(bp = pushdown(data, 5))) {
  906.       free_p(data);
  907.       return;
  908.     }
  909.     bp->data[0] = pc->remoteindex;
  910.     bp->data[1] = pc->remoteid;
  911.     bp->data[2] = 0;
  912.     bp->data[3] = 0;
  913.     bp->data[4] = opcode;
  914.     break;
  915.   case NR4OPINFO:
  916.     start_t1_timer = 1;
  917.   case NR4OPACK:
  918.     if (!(bp = pushdown(data, 5))) {
  919.       free_p(data);
  920.       return;
  921.     }
  922.     if (pc->reseq && !pc->naksent) {
  923.       opcode |= NR4NAK;
  924.       pc->naksent = 1;
  925.     }
  926.     if (pc->chokesent = busy(pc)) opcode |= NR4CHOKE;
  927.     stop_timer(&pc->timer_t2);
  928.     bp->data[0] = pc->remoteindex;
  929.     bp->data[1] = pc->remoteid;
  930.     bp->data[2] = pc->send_state;
  931.     bp->data[3] = pc->recv_state;
  932.     bp->data[4] = opcode;
  933.     if ((opcode & NR4OPCODE) == NR4OPINFO)
  934.       pc->send_state = uchar(pc->send_state + 1);
  935.     break;
  936.   }
  937.   if (start_t1_timer) start_timer(&pc->timer_t1);
  938.   send_l3_packet(Mycall, pc->node, nr_ttlinit, bp);
  939. }
  940.  
  941. /*---------------------------------------------------------------------------*/
  942.  
  943. static void try_send(pc, fill_sndq)
  944. struct circuit *pc;
  945. int  fill_sndq;
  946. {
  947.  
  948.   int  cnt;
  949.   struct mbuf *bp;
  950.  
  951.   stop_timer(&pc->timer_t5);
  952.   while (pc->unack < pc->cwind) {
  953.     if (pc->state != CONNECTED || pc->remote_busy) return;
  954.     if (fill_sndq && pc->t_upcall) {
  955.       cnt = space_nr(pc);
  956.       if (cnt > 0) {
  957.     (*pc->t_upcall)(pc, cnt);
  958.     if (pc->unack >= pc->cwind) return;
  959.       }
  960.     }
  961.     if (!pc->sndq) return;
  962.     cnt = len_p(pc->sndq);
  963.     if (cnt < NR4MAXINFO) {
  964.       if (pc->unack) return;
  965.       if (pc->sndqtime + 1000 - msclock() > 0) {
  966.     set_timer(&pc->timer_t5, pc->sndqtime + 1000 - msclock());
  967.     start_timer(&pc->timer_t5);
  968.     return;
  969.       }
  970.     }
  971.     if (cnt > NR4MAXINFO) cnt = NR4MAXINFO;
  972.     if (!(bp = alloc_mbuf(cnt))) return;
  973.     pullup(&pc->sndq, bp->data, bp->cnt = cnt);
  974.     enqueue(&pc->resndq, bp);
  975.     pc->unack++;
  976.     pc->sndtime[pc->send_state] = msclock();
  977.     dup_p(&bp, bp, 0, cnt);
  978.     send_l4_packet(pc, NR4OPINFO, bp);
  979.   }
  980. }
  981.  
  982. /*---------------------------------------------------------------------------*/
  983.  
  984. static void set_circuit_state(pc, newstate)
  985. struct circuit *pc;
  986. int  newstate;
  987. {
  988.   int  oldstate;
  989.  
  990.   oldstate = pc->state;
  991.   pc->state = newstate;
  992.   pc->retry = 0;
  993.   stop_timer(&pc->timer_t1);
  994.   stop_timer(&pc->timer_t2);
  995.   stop_timer(&pc->timer_t4);
  996.   stop_timer(&pc->timer_t5);
  997.   reset_t1(pc);
  998.   switch (newstate) {
  999.   case DISCONNECTED:
  1000.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1001.     break;
  1002.   case CONNECTING:
  1003.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1004.     send_l4_packet(pc, NR4OPCONRQ, NULLBUF);
  1005.     break;
  1006.   case CONNECTED:
  1007.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1008.     try_send(pc, 1);
  1009.     break;
  1010.   case DISCONNECTING:
  1011.     if (pc->s_upcall) (*pc->s_upcall)(pc, oldstate, newstate);
  1012.     send_l4_packet(pc, NR4OPDISRQ, NULLBUF);
  1013.     break;
  1014.   }
  1015. }
  1016.  
  1017. /*---------------------------------------------------------------------------*/
  1018.  
  1019. static void l4_t1_timeout(pc)
  1020. struct circuit *pc;
  1021. {
  1022.   struct mbuf *bp, *qp;
  1023.  
  1024.   inc_t1(pc);
  1025.   pc->cwind = 1;
  1026.   if (++pc->retry > nr_tretry) pc->reason = TIMEOUT;
  1027.   switch (pc->state) {
  1028.   case DISCONNECTED:
  1029.     break;
  1030.   case CONNECTING:
  1031.     if (pc->retry > nr_tretry)
  1032.       set_circuit_state(pc, DISCONNECTED);
  1033.     else
  1034.       send_l4_packet(pc, NR4OPCONRQ, NULLBUF);
  1035.     break;
  1036.   case CONNECTED:
  1037.     if (pc->retry > nr_tretry)
  1038.       set_circuit_state(pc, DISCONNECTING);
  1039.     else if (pc->unack) {
  1040.       pc->send_state = uchar(pc->send_state - pc->unack);
  1041.       for (qp = pc->resndq; qp; qp = qp->anext) {
  1042.     pc->sndtime[pc->send_state] = 0;
  1043.     dup_p(&bp, qp, 0, NR4MAXINFO);
  1044.     send_l4_packet(pc, NR4OPINFO, bp);
  1045.       }
  1046.     }
  1047.     break;
  1048.   case DISCONNECTING:
  1049.     if (pc->retry > nr_tretry)
  1050.       set_circuit_state(pc, DISCONNECTED);
  1051.     else
  1052.       send_l4_packet(pc, NR4OPDISRQ, NULLBUF);
  1053.     break;
  1054.   }
  1055. }
  1056.  
  1057. /*---------------------------------------------------------------------------*/
  1058.  
  1059. static void l4_t2_timeout(pc)
  1060. struct circuit *pc;
  1061. {
  1062.   send_l4_packet(pc, NR4OPACK, NULLBUF);
  1063. }
  1064.  
  1065. /*---------------------------------------------------------------------------*/
  1066.  
  1067. static void l4_t3_timeout(pc)
  1068. struct circuit *pc;
  1069. {
  1070.   if (!run_timer(&pc->timer_t1)) close_nr(pc);
  1071. }
  1072.  
  1073. /*---------------------------------------------------------------------------*/
  1074.  
  1075. static void l4_t4_timeout(pc)
  1076. struct circuit *pc;
  1077. {
  1078.   pc->remote_busy = 0;
  1079.   if (pc->unack) start_timer(&pc->timer_t1);
  1080.   try_send(pc, 1);
  1081. }
  1082.  
  1083. /*---------------------------------------------------------------------------*/
  1084.  
  1085. static void l4_t5_timeout(pc)
  1086. struct circuit *pc;
  1087. {
  1088.   try_send(pc, 1);
  1089. }
  1090.  
  1091. /*---------------------------------------------------------------------------*/
  1092.  
  1093. static struct circuit *create_circuit()
  1094. {
  1095.  
  1096.   static int  nextid;
  1097.   struct circuit *pc;
  1098.  
  1099.   pc = (struct circuit *) calloc(1, sizeof(struct circuit ));
  1100.   nextid++;
  1101.   pc->localindex = uchar(nextid >> 8);
  1102.   pc->localid = uchar(nextid);
  1103.   pc->remoteindex = -1;
  1104.   pc->remoteid = -1;
  1105.   pc->cwind = 1;
  1106.   pc->srtt = 500L * nr_ttimeout;
  1107.   pc->mdev = pc->srtt / 2;
  1108.   reset_t1(pc);
  1109.   pc->timer_t1.func = (void (*) __ARGS((void *))) l4_t1_timeout;
  1110.   pc->timer_t1.arg = pc;
  1111.   pc->timer_t2.func = (void (*) __ARGS((void *))) l4_t2_timeout;
  1112.   pc->timer_t2.arg = pc;
  1113.   pc->timer_t3.func = (void (*) __ARGS((void *))) l4_t3_timeout;
  1114.   pc->timer_t3.arg = pc;
  1115.   pc->timer_t4.func = (void (*) __ARGS((void *))) l4_t4_timeout;
  1116.   pc->timer_t4.arg = pc;
  1117.   pc->timer_t5.func = (void (*) __ARGS((void *))) l4_t5_timeout;
  1118.   pc->timer_t5.arg = pc;
  1119.   pc->next = circuits;
  1120.   return circuits = pc;
  1121. }
  1122.  
  1123. /*---------------------------------------------------------------------------*/
  1124.  
  1125. static void circuit_manager(bp)
  1126. struct mbuf *bp;
  1127. {
  1128.  
  1129.   int  nakrcvd;
  1130.   struct circuit *pc;
  1131.  
  1132.   if (!bp || bp->cnt < 5) goto discard;
  1133.  
  1134.   if ((bp->data[4] & NR4OPCODE) == NR4OPCONRQ) {
  1135.     if (bp->cnt != 20) goto discard;
  1136.     for (pc = circuits; pc; pc = pc->next)
  1137.       if (pc->remoteindex == uchar(bp->data[0]) &&
  1138.       pc->remoteid == uchar(bp->data[1]) &&
  1139.       addreq(pc->cuser, bp->data + 6) &&
  1140.       addreq(pc->node, bp->data + 13)) break;
  1141.     if (!pc) {
  1142.       pc = create_circuit();
  1143.       pc->remoteindex = uchar(bp->data[0]);
  1144.       pc->remoteid = uchar(bp->data[1]);
  1145.       addrcp(pc->cuser, bp->data + 6);
  1146.       addrcp(pc->node, bp->data + 13);
  1147.       pc->r_upcall = nrserv_recv_upcall;
  1148.       pc->t_upcall = nrserv_send_upcall;
  1149.       pc->s_upcall = nrserv_state_upcall;
  1150.     }
  1151.   } else
  1152.     for (pc = circuits; ; pc = pc->next) {
  1153.       if (!pc) goto discard;
  1154.       if (pc->localindex == uchar(bp->data[0]) &&
  1155.       pc->localid == uchar(bp->data[1])) break;
  1156.     }
  1157.  
  1158.   set_timer(&pc->timer_t3, nr_timeout * 1000L);
  1159.   start_timer(&pc->timer_t3);
  1160.  
  1161.   switch (bp->data[4] & NR4OPCODE) {
  1162.  
  1163.   case NR4OPCONRQ:
  1164.     switch (pc->state) {
  1165.     case DISCONNECTED:
  1166.       pc->window = uchar(bp->data[5]);
  1167.       if (pc->window > nr_twindow) pc->window = nr_twindow;
  1168.       if (pc->window < 1) pc->window = 1;
  1169.       if (server_enabled) {
  1170.     send_l4_packet(pc, NR4OPCONAK, NULLBUF);
  1171.     set_circuit_state(pc, CONNECTED);
  1172.       } else {
  1173.     send_l4_packet(pc, NR4OPCONAK | NR4CHOKE, NULLBUF);
  1174.     del_nr(pc);
  1175.       }
  1176.       break;
  1177.     case CONNECTED:
  1178.       send_l4_packet(pc, NR4OPCONAK, NULLBUF);
  1179.       break;
  1180.     default:
  1181.       goto discard;
  1182.     }
  1183.     break;
  1184.  
  1185.   case NR4OPCONAK:
  1186.     if (pc->state != CONNECTING) goto discard;
  1187.     pc->remoteindex = uchar(bp->data[2]);
  1188.     pc->remoteid = uchar(bp->data[3]);
  1189.     if (pc->window > uchar(bp->data[5])) pc->window = uchar(bp->data[5]);
  1190.     if (pc->window < 1) pc->window = 1;
  1191.     if (bp->data[4] & NR4CHOKE) {
  1192.       pc->reason = RESET;
  1193.       set_circuit_state(pc, DISCONNECTED);
  1194.     } else
  1195.       set_circuit_state(pc, CONNECTED);
  1196.     break;
  1197.  
  1198.   case NR4OPDISRQ:
  1199.     send_l4_packet(pc, NR4OPDISAK, NULLBUF);
  1200.     set_circuit_state(pc, DISCONNECTED);
  1201.     break;
  1202.  
  1203.   case NR4OPDISAK:
  1204.     if (pc->state != DISCONNECTING) goto discard;
  1205.     set_circuit_state(pc, DISCONNECTED);
  1206.     break;
  1207.  
  1208.   case NR4OPINFO:
  1209.   case NR4OPACK:
  1210.     if (pc->state != CONNECTED) goto discard;
  1211.     stop_timer(&pc->timer_t1);
  1212.     if (bp->data[4] & NR4CHOKE) {
  1213.       if (!pc->remote_busy) pc->remote_busy = msclock();
  1214.       set_timer(&pc->timer_t4, nr_tbsydelay * 1000L);
  1215.       start_timer(&pc->timer_t4);
  1216.       pc->cwind = 1;
  1217.     } else {
  1218.       pc->remote_busy = 0;
  1219.       stop_timer(&pc->timer_t4);
  1220.     }
  1221.     if (uchar(pc->send_state - bp->data[3]) < pc->unack) {
  1222.       pc->retry = 0;
  1223.       if (pc->sndtime[uchar(bp->data[3]-1)]) {
  1224.     int32 rtt = msclock() - pc->sndtime[uchar(bp->data[3]-1)];
  1225.     int32 abserr = (rtt > pc->srtt) ? rtt - pc->srtt : pc->srtt - rtt;
  1226.     pc->srtt = ((AGAIN - 1) * pc->srtt + rtt + (AGAIN / 2)) / AGAIN;
  1227.     pc->mdev = ((DGAIN - 1) * pc->mdev + abserr + (DGAIN / 2)) / DGAIN;
  1228.     reset_t1(pc);
  1229.     if (pc->cwind < pc->window && !pc->remote_busy) {
  1230.       pc->mdev += ((pc->srtt / pc->cwind) / 2);
  1231.       pc->cwind++;
  1232.     }
  1233.       }
  1234.       while (uchar(pc->send_state - bp->data[3]) < pc->unack) {
  1235.     pc->resndq = free_p(pc->resndq);
  1236.     pc->unack--;
  1237.       }
  1238.     }
  1239.     nakrcvd = bp->data[4] & NR4NAK;
  1240.     if ((bp->data[4] & NR4OPCODE) == NR4OPINFO) {
  1241.       set_timer(&pc->timer_t2, nr_tackdelay);
  1242.       start_timer(&pc->timer_t2);
  1243.       if (uchar(bp->data[2] - pc->recv_state) < pc->window) {
  1244.     struct mbuf *curr, *prev;
  1245.     for (curr = pc->reseq; curr && curr->data[2] != bp->data[2]; curr = curr->anext) ;
  1246.     if (!curr) {
  1247.       bp->anext = pc->reseq;
  1248.       pc->reseq = bp;
  1249.       bp = NULLBUF;
  1250. search_again:
  1251.       for (prev = 0, curr = pc->reseq; curr; prev = curr, curr = curr->anext)
  1252.         if (uchar(curr->data[2]) == pc->recv_state) {
  1253.           if (prev)
  1254.         prev->anext = curr->anext;
  1255.           else
  1256.         pc->reseq = curr->anext;
  1257.           curr->anext = NULLBUF;
  1258.           pullup(&curr, NULLCHAR, 5);
  1259.           if (curr) {
  1260.         pc->rcvcnt += len_p(curr);
  1261.         append(&pc->rcvq, curr);
  1262.           }
  1263.           pc->recv_state = uchar(pc->recv_state + 1);
  1264.           pc->naksent = 0;
  1265.           goto search_again;
  1266.         }
  1267.       if (pc->r_upcall && pc->rcvcnt) (*pc->r_upcall)(pc, pc->rcvcnt);
  1268.     }
  1269.       }
  1270.     }
  1271.     if (nakrcvd && pc->unack) {
  1272.       int  old_send_state;
  1273.       struct mbuf *bp1;
  1274.       old_send_state = pc->send_state;
  1275.       pc->send_state = uchar(pc->send_state - pc->unack);
  1276.       pc->sndtime[pc->send_state] = 0;
  1277.       dup_p(&bp1, pc->resndq, 0, NR4MAXINFO);
  1278.       send_l4_packet(pc, NR4OPINFO, bp1);
  1279.       pc->send_state = old_send_state;
  1280.       pc->cwind = 1;
  1281.     }
  1282.     try_send(pc, 1);
  1283.     if (pc->unack && !pc->remote_busy) start_timer(&pc->timer_t1);
  1284.     if (pc->closed && !pc->sndq && !pc->unack)
  1285.       set_circuit_state(pc, DISCONNECTING);
  1286.     break;
  1287.   }
  1288.  
  1289. discard:
  1290.   free_p(bp);
  1291. }
  1292.  
  1293. /*---------------------------------------------------------------------------*/
  1294. /********************************* User Calls ********************************/
  1295. /*---------------------------------------------------------------------------*/
  1296.  
  1297. struct circuit *open_nr(node, cuser, window, r_upcall, t_upcall, s_upcall, user)
  1298. char  *node, *cuser;
  1299. int  window;
  1300. void (*r_upcall) __ARGS((struct circuit *p, int cnt));
  1301. void (*t_upcall) __ARGS((struct circuit *p, int cnt));
  1302. void (*s_upcall) __ARGS((struct circuit *p, int oldstate, int newstate));
  1303. char  *user;
  1304. {
  1305.   struct circuit *pc;
  1306.  
  1307.   if (!isnetrom(node)) {
  1308.     Net_error = INVALID;
  1309.     return 0;
  1310.   }
  1311.   if (!cuser) cuser = Mycall;
  1312.   if (!window) window = nr_twindow;
  1313.   if (!(pc = create_circuit())) {
  1314.     Net_error = NO_MEM;
  1315.     return 0;
  1316.   }
  1317.   pc->outbound = 1;
  1318.   addrcp(pc->node, node);
  1319.   addrcp(pc->cuser, cuser);
  1320.   pc->window = window;
  1321.   pc->r_upcall = r_upcall;
  1322.   pc->t_upcall = t_upcall;
  1323.   pc->s_upcall = s_upcall;
  1324.   pc->user = user;
  1325.   set_circuit_state(pc, CONNECTING);
  1326.   return pc;
  1327. }
  1328.  
  1329. /*---------------------------------------------------------------------------*/
  1330.  
  1331. int  send_nr(pc, bp)
  1332. struct circuit *pc;
  1333. struct mbuf *bp;
  1334. {
  1335.   int cnt;
  1336.  
  1337.   if (!(pc && bp)) {
  1338.     free_p(bp);
  1339.     Net_error = INVALID;
  1340.     return (-1);
  1341.   }
  1342.   switch (pc->state) {
  1343.   case DISCONNECTED:
  1344.     free_p(bp);
  1345.     Net_error = NO_CONN;
  1346.     return (-1);
  1347.   case CONNECTING:
  1348.   case CONNECTED:
  1349.     if (!pc->closed) {
  1350.       if (cnt = len_p(bp)) {
  1351.     append(&pc->sndq, bp);
  1352.     pc->sndqtime = msclock();
  1353.     try_send(pc, 0);
  1354.       }
  1355.       return cnt;
  1356.     }
  1357.   case DISCONNECTING:
  1358.     free_p(bp);
  1359.     Net_error = CON_CLOS;
  1360.     return (-1);
  1361.   }
  1362.   return (-1);
  1363. }
  1364.  
  1365. /*---------------------------------------------------------------------------*/
  1366.  
  1367. int  space_nr(pc)
  1368. struct circuit *pc;
  1369. {
  1370.   int  cnt;
  1371.  
  1372.   if (!pc) {
  1373.     Net_error = INVALID;
  1374.     return (-1);
  1375.   }
  1376.   switch (pc->state) {
  1377.   case DISCONNECTED:
  1378.     Net_error = NO_CONN;
  1379.     return (-1);
  1380.   case CONNECTING:
  1381.   case CONNECTED:
  1382.     if (!pc->closed) {
  1383.       cnt = (pc->cwind - pc->unack) * NR4MAXINFO - len_p(pc->sndq);
  1384.       return (cnt > 0) ? cnt : 0;
  1385.     }
  1386.   case DISCONNECTING:
  1387.     Net_error = CON_CLOS;
  1388.     return (-1);
  1389.   }
  1390.   return (-1);
  1391. }
  1392.  
  1393. /*---------------------------------------------------------------------------*/
  1394.  
  1395. int  recv_nr(pc, bpp, cnt)
  1396. struct circuit *pc;
  1397. struct mbuf **bpp;
  1398. int cnt;
  1399. {
  1400.   if (!(pc && bpp)) {
  1401.     Net_error = INVALID;
  1402.     return (-1);
  1403.   }
  1404.   if (pc->rcvcnt) {
  1405.     if (!cnt || pc->rcvcnt <= cnt) {
  1406.       *bpp = dequeue(&pc->rcvq);
  1407.       cnt = len_p(*bpp);
  1408.     } else {
  1409.       if (!(*bpp = alloc_mbuf(cnt))) {
  1410.     Net_error = NO_MEM;
  1411.     return (-1);
  1412.       }
  1413.       pullup(&pc->rcvq, (*bpp)->data, cnt);
  1414.       (*bpp)->cnt = cnt;
  1415.     }
  1416.     pc->rcvcnt -= cnt;
  1417.     if (pc->chokesent && !busy(pc)) {
  1418.       set_timer(&pc->timer_t2, nr_tackdelay);
  1419.       start_timer(&pc->timer_t2);
  1420.     }
  1421.     return cnt;
  1422.   }
  1423.   switch (pc->state) {
  1424.   case CONNECTING:
  1425.   case CONNECTED:
  1426.     *bpp = NULLBUF;
  1427.     Net_error = WOULDBLK;
  1428.     return (-1);
  1429.   case DISCONNECTED:
  1430.   case DISCONNECTING:
  1431.     *bpp = NULLBUF;
  1432.     return 0;
  1433.   }
  1434.   return (-1);
  1435. }
  1436.  
  1437. /*---------------------------------------------------------------------------*/
  1438.  
  1439. int  close_nr(pc)
  1440. struct circuit *pc;
  1441. {
  1442.   if (!pc) {
  1443.     Net_error = INVALID;
  1444.     return (-1);
  1445.   }
  1446.   if (pc->closed) {
  1447.     Net_error = CON_CLOS;
  1448.     return (-1);
  1449.   }
  1450.   pc->closed = 1;
  1451.   switch (pc->state) {
  1452.   case DISCONNECTED:
  1453.     Net_error = NO_CONN;
  1454.     return (-1);
  1455.   case CONNECTING:
  1456.     set_circuit_state(pc, DISCONNECTED);
  1457.     return 0;
  1458.   case CONNECTED:
  1459.     if (!pc->sndq && !pc->unack) set_circuit_state(pc, DISCONNECTING);
  1460.     return 0;
  1461.   case DISCONNECTING:
  1462.     Net_error = CON_CLOS;
  1463.     return (-1);
  1464.   }
  1465.   return (-1);
  1466. }
  1467.  
  1468. /*---------------------------------------------------------------------------*/
  1469.  
  1470. int  reset_nr(pc)
  1471. struct circuit *pc;
  1472. {
  1473.   if (!pc) {
  1474.     Net_error = INVALID;
  1475.     return (-1);
  1476.   }
  1477.   pc->reason = RESET;
  1478.   set_circuit_state(pc, DISCONNECTED);
  1479.   return 0;
  1480. }
  1481.  
  1482. /*---------------------------------------------------------------------------*/
  1483.  
  1484. int  del_nr(pc)
  1485. struct circuit *pc;
  1486. {
  1487.   struct circuit *p, *q;
  1488.  
  1489.   for (q = 0, p = circuits; p != pc; q = p, p = p->next)
  1490.     if (!p) {
  1491.       Net_error = INVALID;
  1492.       return (-1);
  1493.     }
  1494.   if (q)
  1495.     q->next = p->next;
  1496.   else
  1497.     circuits = p->next;
  1498.   stop_timer(&pc->timer_t1);
  1499.   stop_timer(&pc->timer_t2);
  1500.   stop_timer(&pc->timer_t3);
  1501.   stop_timer(&pc->timer_t4);
  1502.   stop_timer(&pc->timer_t5);
  1503.   free_q(&pc->reseq);
  1504.   free_q(&pc->rcvq);
  1505.   free_q(&pc->sndq);
  1506.   free_q(&pc->resndq);
  1507.   free(pc);
  1508.   return 0;
  1509. }
  1510.  
  1511. /*---------------------------------------------------------------------------*/
  1512.  
  1513. int  valid_nr(pc)
  1514. struct circuit *pc;
  1515. {
  1516.   struct circuit *p;
  1517.  
  1518.   if (!pc) return 0;
  1519.   for (p = circuits; p; p = p->next)
  1520.     if (p == pc) return 1;
  1521.   return 0;
  1522. }
  1523.  
  1524. /*---------------------------------------------------------------------------*/
  1525.  
  1526. /* Force a retransmission */
  1527.  
  1528. int  kick_nr(pc)
  1529. struct circuit *pc;
  1530. {
  1531.   if (!valid_nr(pc)) return -1;
  1532.   l4_t1_timeout(pc);
  1533.   return 0;
  1534. }
  1535.  
  1536. /*---------------------------------------------------------------------------*/
  1537. /******************************** Login Server *******************************/
  1538. /*---------------------------------------------------------------------------*/
  1539.  
  1540. #include "login.h"
  1541.  
  1542. /*---------------------------------------------------------------------------*/
  1543.  
  1544. static void nrserv_recv_upcall(pc, cnt)
  1545. struct circuit *pc;
  1546. int  cnt;
  1547. {
  1548.   struct mbuf *bp;
  1549.  
  1550.   recv_nr(pc, &bp, 0);
  1551.   login_write((struct login_cb *) pc->user, bp);
  1552. }
  1553.  
  1554. /*---------------------------------------------------------------------------*/
  1555.  
  1556. static void nrserv_send_upcall(pc, cnt)
  1557. struct circuit *pc;
  1558. int  cnt;
  1559. {
  1560.   struct mbuf *bp;
  1561.  
  1562.   if (bp = login_read((struct login_cb *) pc->user, space_nr(pc)))
  1563.     send_nr(pc, bp);
  1564. }
  1565.  
  1566. /*---------------------------------------------------------------------------*/
  1567.  
  1568. static void nrserv_state_upcall(pc, oldstate, newstate)
  1569. struct circuit *pc;
  1570. int  oldstate, newstate;
  1571. {
  1572.   switch (newstate) {
  1573.   case CONNECTED:
  1574.     pc->user = (char *) login_open(nr_addr2str(pc), "NETROM", (void (*)()) nrserv_send_upcall, (void (*)()) close_nr, pc);
  1575.     if (!pc->user) close_nr(pc);
  1576.     break;
  1577.   case DISCONNECTED:
  1578.     login_close((struct login_cb *) pc->user);
  1579.     del_nr(pc);
  1580.     break;
  1581.   }
  1582. }
  1583.  
  1584. /*---------------------------------------------------------------------------*/
  1585. /*********************************** Client **********************************/
  1586. /*---------------------------------------------------------------------------*/
  1587.  
  1588. #include "session.h"
  1589.  
  1590. /*---------------------------------------------------------------------------*/
  1591.  
  1592. static void nrclient_parse(buf, n)
  1593. char *buf;
  1594. int n;
  1595. {
  1596.   if (!(Current && Current->type == NRSESSION && Current->cb.netrom)) return;
  1597.   if (n >= 1 && buf[n-1] == '\n') n--;
  1598.   if (!n) return;
  1599.   send_nr(Current->cb.netrom, qdata(buf, n));
  1600.   if (Current->record) {
  1601.     if (buf[n-1] == '\r') buf[n-1] = '\n';
  1602.     fwrite(buf, 1, n, Current->record);
  1603.   }
  1604. }
  1605.  
  1606. /*---------------------------------------------------------------------------*/
  1607.  
  1608. void nrclient_send_upcall(pc, cnt)
  1609. struct circuit *pc;
  1610. int  cnt;
  1611. {
  1612.  
  1613.   char  *p;
  1614.   int  chr;
  1615.   struct mbuf *bp;
  1616.   struct session *s;
  1617.  
  1618.   if (!(s = (struct session *) pc->user) || !s->upload || cnt <= 0) return;
  1619.   if (!(bp = alloc_mbuf(cnt))) return;
  1620.   p = bp->data;
  1621.   while (cnt) {
  1622.     if ((chr = getc(s->upload)) == EOF) break;
  1623.     if (chr == '\n') chr = '\r';
  1624.     *p++ = chr;
  1625.     cnt--;
  1626.   }
  1627.   if (bp->cnt = p - bp->data)
  1628.     send_nr(pc, bp);
  1629.   else
  1630.     free_p(bp);
  1631.   if (cnt) {
  1632.     fclose(s->upload);
  1633.     s->upload = 0;
  1634.     free(s->ufile);
  1635.     s->ufile = 0;
  1636.   }
  1637. }
  1638.  
  1639. /*---------------------------------------------------------------------------*/
  1640.  
  1641. void nrclient_recv_upcall(pc, cnt)
  1642. struct circuit *pc;
  1643. int  cnt;
  1644. {
  1645.  
  1646.   int  c;
  1647.   struct mbuf *bp;
  1648.  
  1649.   if (!(Mode == CONV_MODE && Current && Current->type == NRSESSION && Current->cb.netrom == pc)) return;
  1650.   recv_nr(pc, &bp, 0);
  1651.   while ((c = PULLCHAR(&bp)) != -1) {
  1652.     if (c == '\r') c = '\n';
  1653.     putchar(c);
  1654.     if (Current->record) putc(c, Current->record);
  1655.   }
  1656. }
  1657.  
  1658. /*---------------------------------------------------------------------------*/
  1659.  
  1660. static void nrclient_state_upcall(pc, oldstate, newstate)
  1661. struct circuit *pc;
  1662. int  oldstate, newstate;
  1663. {
  1664.   int  notify;
  1665.  
  1666.   notify = (Current && Current->type == NRSESSION && Current == (struct session *) pc->user);
  1667.   if (newstate != DISCONNECTED) {
  1668.     if (notify) printf("%s\n", ax25states[newstate]);
  1669.   } else {
  1670.     if (notify) printf("%s (%s)\n", ax25states[newstate], nrreasons[pc->reason]);
  1671.     if (pc->user) freesession((struct session *) pc->user);
  1672.     del_nr(pc);
  1673.     if (notify) cmdmode();
  1674.   }
  1675. }
  1676.  
  1677. /*---------------------------------------------------------------------------*/
  1678.  
  1679. static int  donconnect(argc, argv, p)
  1680. int  argc;
  1681. char  *argv[];
  1682. void *p;
  1683. {
  1684.  
  1685.   char  node[AXALEN], cuser[AXALEN];
  1686.   struct session *s;
  1687.  
  1688.   if (setcall(node, argv[1])) {
  1689.     printf("Invalid call \"%s\"\n", argv[1]);
  1690.     return 1;
  1691.   }
  1692.   if (!isnetrom(node)) {
  1693.     printf("Unknown node \"%s\"\n", argv[1]);
  1694.     return 1;
  1695.   }
  1696.   if (argc < 3)
  1697.     addrcp(cuser, Mycall);
  1698.   else if (setcall(cuser, argv[2])) {
  1699.     printf("Invalid call \"%s\"\n", argv[2]);
  1700.     return 1;
  1701.   }
  1702.   if (!(s = newsession())) {
  1703.     printf("Too many sessions\n");
  1704.     return 1;
  1705.   }
  1706.   Current = s;
  1707.   s->type = NRSESSION;
  1708.   s->name = NULLCHAR;
  1709.   s->cb.netrom = 0;
  1710.   s->parse = nrclient_parse;
  1711.   if (!(s->cb.netrom = open_nr(node, cuser, 0, nrclient_recv_upcall, nrclient_send_upcall, nrclient_state_upcall, (char *) s))) {
  1712.     freesession(s);
  1713.     switch (Net_error) {
  1714.     case NONE:
  1715.       printf("No error\n");
  1716.       break;
  1717.     case CON_EXISTS:
  1718.       printf("Connection already exists\n");
  1719.       break;
  1720.     case NO_CONN:
  1721.       printf("Connection does not exist\n");
  1722.       break;
  1723.     case CON_CLOS:
  1724.       printf("Connection closing\n");
  1725.       break;
  1726.     case NO_MEM:
  1727.       printf("No memory\n");
  1728.       break;
  1729.     case WOULDBLK:
  1730.       printf("Would block\n");
  1731.       break;
  1732.     case NOPROTO:
  1733.       printf("Protocol or mode not supported\n");
  1734.       break;
  1735.     case INVALID:
  1736.       printf("Invalid arguments\n");
  1737.       break;
  1738.     }
  1739.     return 1;
  1740.   }
  1741.   go(argc, argv, p);
  1742.   return 0;
  1743. }
  1744.  
  1745. /*---------------------------------------------------------------------------*/
  1746. /****************************** NETROM Commands ******************************/
  1747. /*---------------------------------------------------------------------------*/
  1748.  
  1749. int  nr_attach(argc, argv, p)
  1750. int  argc;
  1751. char  *argv[];
  1752. void *p;
  1753. {
  1754.   if (Nr_iface) {
  1755.     tprintf("netrom interface already attached\n");
  1756.     return -1;
  1757.   }
  1758.   Nr_iface = (struct iface *) callocw(1, sizeof(struct iface ));
  1759.   Nr_iface->addr = Ip_addr;
  1760.   Nr_iface->name = strdup("netrom");
  1761.   Nr_iface->hwaddr = mallocw(AXALEN);
  1762.   memcpy(Nr_iface->hwaddr, Mycall, AXALEN);
  1763.   Nr_iface->mtu = NR4MAXINFO;
  1764.   setencap(Nr_iface, "NETROM");
  1765.   Nr_iface->next = Ifaces;
  1766.   Ifaces = Nr_iface;
  1767.   return 0;
  1768. }
  1769.  
  1770. /*---------------------------------------------------------------------------*/
  1771.  
  1772. static int  dobroadcast(argc, argv, p)
  1773. int  argc;
  1774. char  *argv[];
  1775. void *p;
  1776. {
  1777.  
  1778.   char  *hp;
  1779.   char  tmp[AXBUF];
  1780.   int  i;
  1781.   struct broadcast *bp;
  1782.  
  1783.   if (argc < 3) {
  1784.     puts("Interface  Path");
  1785.     for (bp = broadcasts; bp; bp = bp->next) {
  1786.       printf("%-9s", bp->iface->name);
  1787.       printf("  %s", pax25(tmp, bp->iface->hwaddr));
  1788.       printf("->%s", pax25(tmp, bp->hdr.dest));
  1789.       if (bp->hdr.ndigis) {
  1790.     printf(" v");
  1791.     for (hp = bp->hdr.digis[0]; hp < bp->hdr.digis[bp->hdr.ndigis]; hp += AXALEN)
  1792.       printf(" %s", pax25(tmp, hp));
  1793.       }
  1794.       putchar('\n');
  1795.     }
  1796.     return 0;
  1797.   }
  1798.  
  1799.   bp = (struct broadcast *) calloc(1, sizeof(struct broadcast ));
  1800.   if (!(bp->iface = if_lookup(argv[1]))) {
  1801.     printf("Interface \"%s\" unknown\n", argv[1]);
  1802.     free(bp);
  1803.     return 1;
  1804.   }
  1805.   if (bp->iface->output != ax_output) {
  1806.     printf("Interface \"%s\" not kiss\n", argv[1]);
  1807.     free(bp);
  1808.     return 1;
  1809.   }
  1810.   if (setcall(bp->hdr.dest, argv[2])) {
  1811.     printf("Invalid call \"%s\"\n", argv[2]);
  1812.     free(bp);
  1813.     return 1;
  1814.   }
  1815.   for (i = 3; i < argc; i++)
  1816.     if (strncmp("via", argv[i], strlen(argv[i]))) {
  1817.       if (bp->hdr.ndigis >= MAXDIGIS) {
  1818.     printf("Too many digipeaters (max %d)\n", MAXDIGIS);
  1819.     free(bp);
  1820.     return 1;
  1821.       }
  1822.       if (setcall(bp->hdr.digis[bp->hdr.ndigis++], argv[i])) {
  1823.     printf("Invalid call \"%s\"\n", argv[i]);
  1824.     free(bp);
  1825.     return 1;
  1826.       }
  1827.     }
  1828.   bp->hdr.cmdrsp = LAPB_COMMAND;
  1829.   bp->next = broadcasts;
  1830.   broadcasts = bp;
  1831.   return 0;
  1832. }
  1833.  
  1834. /*---------------------------------------------------------------------------*/
  1835.  
  1836. static int  doident(argc, argv, p)
  1837. int  argc;
  1838. char  *argv[];
  1839. void *p;
  1840. {
  1841.  
  1842.   char  *cp;
  1843.   int  i;
  1844.  
  1845.   if (argc < 2)
  1846.     printf("Ident %-6.6s\n", mynode->ident);
  1847.   else {
  1848.     for (cp = argv[1], i = 0; i < IDENTLEN; i++)
  1849.       mynode->ident[i] = *cp ? toupper(*cp++) : ' ';
  1850.   }
  1851.   return 0;
  1852. }
  1853.  
  1854. /*---------------------------------------------------------------------------*/
  1855.  
  1856. /* Force a retransmission */
  1857.  
  1858. static int  donkick(argc, argv, p)
  1859. int  argc;
  1860. char  *argv[];
  1861. void *p;
  1862. {
  1863.   struct circuit *pc;
  1864.  
  1865.   pc = (struct circuit *) ltop(htol(argv[1]));
  1866.   if (!valid_nr(pc)) {
  1867.     tprintf(Notval);
  1868.     return 1;
  1869.   }
  1870.   kick_nr(pc);
  1871.   return 0;
  1872. }
  1873.  
  1874. /*---------------------------------------------------------------------------*/
  1875.  
  1876. static int  dolinks(argc, argv, p)
  1877. int  argc;
  1878. char  *argv[];
  1879. void *p;
  1880. {
  1881.  
  1882.   char  buf1[20], buf2[20];
  1883.   char  call[AXALEN];
  1884.   int  quality;
  1885.   long  timestamp;
  1886.   struct link *pl;
  1887.   struct linkinfo *pi;
  1888.   struct node *pn1, *pn2;
  1889.  
  1890.   if (argc >= 2) {
  1891.     if (setcall(call, argv[1])) {
  1892.       printf("Invalid call \"%s\"\n", argv[1]);
  1893.       return 1;
  1894.     }
  1895.     if (argc > 2)
  1896.       pn1 = nodeptr(call, 1);
  1897.     else if (!(pn1 = nodeptr(call, 0))) {
  1898.       printf("Unknown node \"%s\"\n", argv[1]);
  1899.       return 1;
  1900.     }
  1901.   }
  1902.  
  1903.   if (argc <= 2) {
  1904.     printf("From       To         Level  Quality   Age\n");
  1905.     for (pn2 = nodes; pn2; pn2 = pn2->next)
  1906.       if (argc < 2 || pn1 == pn2) {
  1907.     pax25(buf1, pn2->call);
  1908.     for (pl = pn2->links; pl; pl = pl->next) {
  1909.       pax25(buf2, pl->node->call);
  1910.       if (pl->info->time != PERMANENT)
  1911.         printf("%-9s  %-9s  %5i  %7i  %4i\n", buf1, buf2, pl->info->level, pl->info->quality, secclock() - pl->info->time);
  1912.       else
  1913.         printf("%-9s  %-9s  %5i  %7i\n", buf1, buf2, pl->info->level, pl->info->quality);
  1914.     }
  1915.       }
  1916.     return 0;
  1917.   }
  1918.  
  1919.   if (argc < 4 || argc > 5) {
  1920.     printf("Usage: netrom links [<node> [<node2> <quality> [permanent]]]\n");
  1921.     return 1;
  1922.   }
  1923.  
  1924.   if (setcall(call, argv[2])) {
  1925.     printf("Invalid call \"%s\"\n", argv[2]);
  1926.     return 1;
  1927.   }
  1928.   pn2 = nodeptr(call, 1);
  1929.   if (pn1 == pn2) {
  1930.     printf("Both calls are identical\n");
  1931.     return 1;
  1932.   }
  1933.   if (pn1->level == MAXLEVEL && pn2->level == MAXLEVEL) {
  1934.     printf("Both nodes are unreachable\n");
  1935.     return 1;
  1936.   }
  1937.  
  1938.   quality = atoi(argv[3]);
  1939.   if (quality < 0 || quality > 255) {
  1940.     printf("Quality must be 0..255\n");
  1941.     return 1;
  1942.   }
  1943.  
  1944.   if (argc < 5)
  1945.     timestamp = secclock();
  1946.   else {
  1947.     if (strncmp(argv[4], "permanent", strlen(argv[4]))) {
  1948.       printf("Usage: netrom links [<node> [<node2> <quality> [permanent]]]\n");
  1949.       return 1;
  1950.     }
  1951.     timestamp = PERMANENT;
  1952.   }
  1953.  
  1954.   pi = linkinfoptr(pn1, pn2);
  1955.   pi->quality = quality;
  1956.   pi->level = min(pn1->level, pn2->level) + 1;
  1957.   pi->time = timestamp;
  1958.   calculate_all();
  1959.   return 0;
  1960. }
  1961.  
  1962. /*---------------------------------------------------------------------------*/
  1963.  
  1964. static int  donodes(argc, argv, p)
  1965. int  argc;
  1966. char  *argv[];
  1967. void *p;
  1968. {
  1969.  
  1970.   char  buf1[20], buf2[20];
  1971.   char  call[AXALEN];
  1972.   struct node *pn, *pn1;
  1973.  
  1974.   if (argc >= 2) {
  1975.     if (setcall(call, argv[1])) {
  1976.       printf("Invalid call \"%s\"\n", argv[1]);
  1977.       return 1;
  1978.     }
  1979.     if (!(pn1 = nodeptr(call, 0))) {
  1980.       printf("Unknown node \"%s\"\n", argv[1]);
  1981.       return 1;
  1982.     }
  1983.   }
  1984.   printf("Node       Ident   Neighbor   Level  Quality\n");
  1985.   for (pn = nodes; pn; pn = pn->next)
  1986.     if (argc < 2 || pn == pn1) {
  1987.       pax25(buf1, pn->call);
  1988.       if (pn->neighbor)
  1989.     pax25(buf2, pn->neighbor->call);
  1990.       else
  1991.     *buf2 = '\0';
  1992.       printf("%-9s  %-6.6s  %-9s  %5i  %7i\n", buf1, pn->ident, buf2, pn->level, (int) pn->quality);
  1993.     }
  1994.   return 0;
  1995. }
  1996.  
  1997. /*---------------------------------------------------------------------------*/
  1998.  
  1999. static int  doparms(argc, argv, p)
  2000. int  argc;
  2001. char  *argv[];
  2002. void *p;
  2003. {
  2004.   int  i, j;
  2005.  
  2006.   switch (argc) {
  2007.   case 0:
  2008.   case 1:
  2009.     for (i = 1; i <= NPARMS; i++)
  2010.       printf("%s %10d\n", parms[i].text, *parms[i].valptr);
  2011.     return 0;
  2012.   case 2:
  2013.   case 3:
  2014.     i = atoi(argv[1]);
  2015.     if (i < 1 || i > NPARMS) {
  2016.       printf("parameter # must be 1..%d\n", NPARMS);
  2017.       return 1;
  2018.     }
  2019.     if (argc == 2) {
  2020.       printf("%s %10d\n", parms[i].text, *parms[i].valptr);
  2021.       return 0;
  2022.     }
  2023.     j = atoi(argv[2]);
  2024.     if (j < parms[i].minval || j > parms[i].maxval) {
  2025.       printf("parameter %d must be %d..%d\n", i, parms[i].minval, parms[i].maxval);
  2026.       return 1;
  2027.     }
  2028.     *parms[i].valptr = j;
  2029.     if (dur_timer(&broadcast_timer) != nr_bdcstint * 1000L) {
  2030.       set_timer(&broadcast_timer, nr_bdcstint * 1000L);
  2031.       start_timer(&broadcast_timer);
  2032.     }
  2033.     return 0;
  2034.   default:
  2035.     printf("Usage: netrom parms [<parm#> [<parm value>]]\n");
  2036.     return 1;
  2037.   }
  2038. }
  2039.  
  2040. /*---------------------------------------------------------------------------*/
  2041.  
  2042. static int  donreset(argc, argv, p)
  2043. int  argc;
  2044. char  *argv[];
  2045. void *p;
  2046. {
  2047.   struct circuit *pc;
  2048.  
  2049.   pc = (struct circuit *) htol(argv[1]);
  2050.   if (!valid_nr(pc)) {
  2051.     printf(Notval);
  2052.     return 1;
  2053.   }
  2054.   reset_nr(pc);
  2055.   return 0;
  2056. }
  2057.  
  2058. /*---------------------------------------------------------------------------*/
  2059.  
  2060. static int  donstatus(argc, argv, p)
  2061. int  argc;
  2062. char  *argv[];
  2063. void *p;
  2064. {
  2065.  
  2066.   int  i;
  2067.   struct circuit *pc;
  2068.   struct mbuf *bp;
  2069.  
  2070.   if (argc < 2) {
  2071.     if (!Shortstatus)
  2072.       printf("bdcsts rcvd %d bdcsts sent %d\n", routes_stat.rcvd, routes_stat.sent);
  2073.     printf("   &NRCB Rcv-Q Unack  Rt  Srtt  State          Remote socket\n");
  2074.     for (pc = circuits; pc; pc = pc->next)
  2075.       printf("%8lx %5u%c%3u/%u%c %2d %5.1f  %-13s  %s\n",
  2076.          (long) pc,
  2077.          pc->rcvcnt,
  2078.          pc->chokesent ? '*' : ' ',
  2079.          pc->unack,
  2080.          pc->cwind,
  2081.          pc->remote_busy ? '*' : ' ',
  2082.          pc->retry,
  2083.          pc->srtt / 1000.0,
  2084.          ax25states[pc->state],
  2085.          nr_addr2str(pc));
  2086.     if (server_enabled)
  2087.       printf("                                Listen (S)     *\n");
  2088.   } else {
  2089.     pc = (struct circuit *) htol(argv[1]);
  2090.     if (!valid_nr(pc)) {
  2091.       printf("Not a valid control block address\n");
  2092.       return 1;
  2093.     }
  2094.     printf("Address:      %s\n", nr_addr2str(pc));
  2095.     printf("Remote id:    %d/%d\n", pc->remoteindex, pc->remoteid);
  2096.     printf("Local id:     %d/%d\n", pc->localindex, pc->localid);
  2097.     printf("State:        %s\n", ax25states[pc->state]);
  2098.     if (pc->reason)
  2099.       printf("Reason:       %s\n", nrreasons[pc->reason]);
  2100.     printf("Window:       %d\n", pc->window);
  2101.     printf("NAKsent:      %s\n", pc->naksent ? "Yes" : "No");
  2102.     printf("CHOKEsent:    %s\n", pc->chokesent ? "Yes" : "No");
  2103.     printf("Closed:       %s\n", pc->closed ? "Yes" : "No");
  2104.     if (pc->remote_busy)
  2105.       printf("Remote_busy:  %lu ms\n", msclock() - pc->remote_busy);
  2106.     else
  2107.       printf("Remote_busy:  No\n");
  2108.     printf("CWind:        %d\n", pc->cwind);
  2109.     printf("Retry:        %d\n", pc->retry);
  2110.     printf("Srtt:         %ld ms\n", pc->srtt);
  2111.     printf("Mean dev:     %ld ms\n", pc->mdev);
  2112.     tprintf("Timer T1:     ");
  2113.     if (run_timer(&pc->timer_t1))
  2114.       tprintf("%lu", read_timer(&pc->timer_t1));
  2115.     else
  2116.       tprintf("stop");
  2117.     tprintf("/%lu ms\n", dur_timer(&pc->timer_t1));
  2118.     tprintf("Timer T2:     ");
  2119.     if (run_timer(&pc->timer_t2))
  2120.       tprintf("%lu", read_timer(&pc->timer_t2));
  2121.     else
  2122.       tprintf("stop");
  2123.     tprintf("/%lu ms\n", dur_timer(&pc->timer_t2));
  2124.     tprintf("Timer T3:     ");
  2125.     if (run_timer(&pc->timer_t3))
  2126.       tprintf("%lu", read_timer(&pc->timer_t3));
  2127.     else
  2128.       tprintf("stop");
  2129.     tprintf("/%lu ms\n", dur_timer(&pc->timer_t3));
  2130.     tprintf("Timer T4:     ");
  2131.     if (run_timer(&pc->timer_t4))
  2132.       tprintf("%lu", read_timer(&pc->timer_t4));
  2133.     else
  2134.       tprintf("stop");
  2135.     tprintf("/%lu ms\n", dur_timer(&pc->timer_t4));
  2136.     tprintf("Timer T5:     ");
  2137.     if (run_timer(&pc->timer_t5))
  2138.       tprintf("%lu", read_timer(&pc->timer_t5));
  2139.     else
  2140.       tprintf("stop");
  2141.     tprintf("/%lu ms\n", dur_timer(&pc->timer_t5));
  2142.     printf("Rcv queue:    %d\n", pc->rcvcnt);
  2143.     if (pc->reseq) {
  2144.       printf("Reassembly queue:\n");
  2145.       for (bp = pc->reseq; bp; bp = bp->anext)
  2146.     printf("              Seq %3d: %3d bytes\n", uchar(bp->data[2]), len_p(bp));
  2147.     }
  2148.     printf("Snd queue:    %d\n", len_p(pc->sndq));
  2149.     if (pc->resndq) {
  2150.       printf("Resend queue:\n");
  2151.       for (i = 0, bp = pc->resndq; bp; i++, bp = bp->anext)
  2152.     printf("              Seq %3d: %3d bytes\n",
  2153.            uchar(pc->send_state - pc->unack + i), len_p(bp));
  2154.     }
  2155.   }
  2156.   return 0;
  2157. }
  2158.  
  2159. /*---------------------------------------------------------------------------*/
  2160.  
  2161. int  donetrom(argc, argv, p)
  2162. int  argc;
  2163. char  *argv[];
  2164. void *p;
  2165. {
  2166.  
  2167.   static struct cmds netromcmds[] = {
  2168.     "broadcast",dobroadcast,0, 0, NULLCHAR,
  2169.     "connect",  donconnect, 0, 2, "netrom connect <node> [<user>]",
  2170.     "ident",    doident,    0, 0, NULLCHAR,
  2171.     "kick",     donkick,    0, 2, "netrom kick <nrcb>",
  2172.     "links",    dolinks,    0, 0, NULLCHAR,
  2173.     "nodes",    donodes,    0, 0, NULLCHAR,
  2174.     "parms",    doparms,    0, 0, NULLCHAR,
  2175.     "reset",    donreset,   0, 2, "netrom reset <nrcb>",
  2176.     "status",   donstatus,  0, 0, NULLCHAR,
  2177.     NULLCHAR,   NULLFP,     0, 0, NULLCHAR
  2178.   };
  2179.  
  2180.   return subcmd(netromcmds, argc, argv, p);
  2181. }
  2182.  
  2183. /*---------------------------------------------------------------------------*/
  2184.  
  2185. int  nr4start(argc, argv, p)
  2186. int  argc;
  2187. char  *argv[];
  2188. void *p;
  2189. {
  2190.   server_enabled = 1;
  2191.   return 0;
  2192. }
  2193.  
  2194. /*---------------------------------------------------------------------------*/
  2195.  
  2196. int  nr40(argc, argv, p)
  2197. int  argc;
  2198. char  *argv[];
  2199. void *p;
  2200. {
  2201.   server_enabled = 0;
  2202.   return 0;
  2203. }
  2204.  
  2205. /*---------------------------------------------------------------------------*/
  2206. /*---------------------------------------------------------------------------*/
  2207. /*---------------------------------------------------------------------------*/
  2208.  
  2209. void netrom_initialize()
  2210. {
  2211.   link_manager_initialize();
  2212.   routing_manager_initialize();
  2213. }
  2214.  
  2215.